package com.blog.blogservice.util;

import com.blog.blogservice.domain.entity.MinIoConfigProperties;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.PutObjectOptions;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidBucketNameException;
import io.minio.errors.InvalidResponseException;
import io.minio.errors.RegionConflictException;
import io.minio.errors.XmlParserException;
import org.apache.pdfbox.io.IOUtils;
import org.jsoup.helper.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;

/**
 * @author guanglin.ma
 * @date 2024-03-03 21:05
 */
@Service
public class MinIOUtil {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinIoConfigProperties minIOConfigProperties;

    /**
     * 上传
     */
    public String putObject(MultipartFile multipartFile) throws Exception {
        // bucket 不存在，创建
        if (!minioClient.bucketExists(minIOConfigProperties.getBucketName())) {
            minioClient.makeBucket(minIOConfigProperties.getBucketName());
        }
        try (InputStream inputStream = multipartFile.getInputStream()) {
            // 上传文件的名称
            String fileName = String.valueOf(Instant.now().toEpochMilli());
            // PutObjectOptions，上传配置(文件大小，内存中文件分片大小)
            PutObjectOptions putObjectOptions = new PutObjectOptions(multipartFile.getSize(),
                    PutObjectOptions.MIN_MULTIPART_SIZE);
            // 文件的ContentType
            putObjectOptions.setContentType(multipartFile.getContentType());
            minioClient.putObject(minIOConfigProperties.getBucketName(), fileName, inputStream, putObjectOptions);
            // 返回访问路径
            return minIOConfigProperties.getEndpoint() + "/" + minIOConfigProperties.getBucketName() +
                    "/" + UriUtils.encode(fileName, StandardCharsets.UTF_8);
        }
    }

    /**
     * 文件下载
     */
    public void download(String fileName, HttpServletResponse response) {
        // 从链接中得到文件名
        InputStream inputStream;
        try {
            MinioClient minioClient = new MinioClient(minIOConfigProperties.getEndpoint(),
                    minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey());
            ObjectStat stat = minioClient.statObject(minIOConfigProperties.getBucketName(), fileName);
            inputStream = minioClient.getObject(minIOConfigProperties.getBucketName(), fileName);
            response.setContentType(stat.contentType());
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            IOUtils.copy(inputStream, response.getOutputStream());
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("有异常：" + e);
        }
    }

    /**
     * 删除文件
     *
     * @param bucketName
     * @param objectName
     */
    public void deleteFile(String bucketName, String objectName) throws InvalidBucketNameException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, RegionConflictException {
        // bucket 不存在，创建
        if (!minioClient.bucketExists(minIOConfigProperties.getBucketName())) {
            minioClient.makeBucket(minIOConfigProperties.getBucketName());
        }
        minioClient.removeObject(bucketName, objectName);
    }


    /**
     * 检查存储桶是否存在
     *
     * @param bucketName
     * @return
     * @throws Exception
     */
    public boolean bucketExists(String bucketName) throws Exception {
        boolean flag = minioClient.bucketExists(bucketName);
        if (flag) {
            return true;
        }
        return false;
    }

    /**
     * 文件访问路径
     *
     * @param bucketName 存储桶名称
     * @param objectName 存储桶里的对象名称
     * @return
     * @throws Exception
     */
    public String getObjectUrl(String bucketName, String objectName) throws Exception {
        boolean flag = bucketExists(bucketName);
        String url = "";
        if (flag) {
            url = minioClient.getObjectUrl(bucketName, objectName);
        }
        return url;
    }

    /**
     * 访问路径拆分
     *
     * @param url
     * @return
     */
    public static List<String> getUrlAnalysis(String url) {
        // todo  http://127.0.0.1:9000/bucket001/1709717135226
        if (!StringUtil.isBlank(url)) {
            String[] values = url.split("/");

            return Arrays.asList(values);
        }
        return null;
    }

}
